/*
 * @Author: Zhouhai 497675647@qq.com
 * @Date: 2022-08-17 11:53:52
 * @LastEditors: Zhouhai 497675647@qq.com
 * @LastEditTime: 2022-11-10 11:49:50
 */
/* eslint-disable @typescript-eslint/no-unused-vars */
import { listMenu } from '@/api/system/menu';
import type { RadioChangeEvent } from 'antd';
import { TreeSelect } from 'antd';
import { Form, Row, Col, Input, Select, Radio } from 'antd';
import type { DefaultOptionType } from 'antd/lib/select';
import React, { useEffect, useState } from 'react'
import './index.less'

const Item = Form.Item;
const { Option } = Select;

export type GenInfoFormProps = {
    datas: Record<string, string>;
    tables: any[],
    culumn: any[],
    onValuesChange?: (changedValues: any, values: any) => void
}


/**
 * 构造树型结构数据
 * @param {*} data 数据源
 * @param {*} id id字段 默认 'id'
 * @param {*} parentId 父节点字段 默认 'parentId'
 * @param {*} children 孩子节点字段 默认 'children'
 */
const handleTree = (data: [], id?: string, parentId?: string, children?: string) => {
    const config = {
        id: id || 'id',
        parentId: parentId || 'parentId',
        childrenList: children || 'children'
    };

    const childrenListMap: Record<string, any[]> = {};
    const nodeIds: Record<string, any> = {};
    const tree: any[] = [];

    for (const d of data) {
        if (childrenListMap[d[config.parentId]] == null) {
            childrenListMap[d[config.parentId]] = [];
        }
        if (d['menuType'] == 'M') {
            const dd = {
                checkable: false,
                disableCheckbox: false,
                disabled: false,
                isLeaf: false,
                key: d[config.id],
                selectable: true,
                title: d['menuName'],
                value: d[config.id]

            };
            nodeIds[d[config.id]] = dd
            childrenListMap[d[config.parentId]].push(dd);
        }
    }

    for (const d of data) {
        if (nodeIds[d[config.parentId]] == null) {
            const dd = {
                checkable: false,
                disableCheckbox: false,
                disabled: false,
                isLeaf: false,
                key: d[config.id],
                selectable: true,
                title: d['menuName'],
                value: d[config.id]

            };
            tree.push(dd);
        }
    }

    for (const t of tree) {
        adaptToChildrenList(t);
    }

    function adaptToChildrenList(o: any) {
        if (childrenListMap[o['key']] !== null) {
            o[config.childrenList] = childrenListMap[o['key']];
        }
        if (o[config.childrenList]) {
            for (const c of o[config.childrenList]) {
                adaptToChildrenList(c);
            }
        }
    }
    return tree;
}

const handleTableOptions = (data: any[]): DefaultOptionType[] => {
    if (data) {
        return data.map((item) => {
            return {
                label: `${item.tableComment} : ${item.tableName}`,
                value: item.tableName,
                columns: item.columns
            } as DefaultOptionType
        })
    }
    return [];
}


const handleTableFieldOptions = (data: any[]): DefaultOptionType[] => {
    if (data) {
        return data.map((item) => {
            return {
                label: `${item.columnComment} : ${item.columnName}`,
                value: item.columnName
            } as DefaultOptionType
        })
    }
    return [];
}

const handleColumnOptions = (data: any[]): DefaultOptionType[] => {
    if (data) {
        return data.map((item) => {
            return {
                label: `${item.columnComment} : ${item.columnName}`,
                value: item.columnName
            } as DefaultOptionType
        })
    }
    return [];
}

const GenInfoForm: React.FC<GenInfoFormProps> = (Props) => {

    const { datas, onValuesChange, tables,culumn } = Props;
    const [form] = Form.useForm();
    const [genType, setGenType] = useState<string>();
    const [treeData, setTreeData] = useState<any>();
    const [tableOptions, setTableOptions] = useState<DefaultOptionType[]>([]);
    const [tableFieldOptions, setTableFieldOptions] = useState<DefaultOptionType[]>([]);
    const [culumnOptions, setColumnOptions] = useState<DefaultOptionType[]>([]);


    useEffect(() => {
        listMenu().then((res) => {
            if (res && res.data) {
                setTreeData(handleTree(res.data, 'menuId'));
            }
        })
        setTableOptions(handleTableOptions(tables));
        setColumnOptions(handleColumnOptions(culumn));
    }, [])


    return (
        <Form
            onValuesChange={onValuesChange}
            initialValues={datas}
            labelWrap
            form={form}
        >
            <Row gutter={[32, 24]}>
                <Col span={12} >
                    <Item label="生成模板" name={"tplCategory"} labelCol={{ span: 4 }} required>
                        <Select placeholder="请选择模板">
                            <Option value="crud">单表（增删改查）</Option>
                            <Option value="tree">树表（增删改查）</Option>
                            <Option value="sub">主子表（增删改查）</Option>
                        </Select>
                    </Item>
                </Col>
                <Col span={12} >
                    <Item label="生成包路径" name={"packageName"} labelCol={{ span: 4 }} tooltip="生成在哪个java包下，例如 com.ruoyi.system" required>
                        <Input placeholder="请输入表描述" />
                    </Item>
                </Col>
                <Col span={12} >
                    <Item label="生成模块名" name={"moduleName"} labelCol={{ span: 4 }} tooltip="可理解为子系统名，例如 system" required>
                        <Input placeholder="请输入模块名" />
                    </Item>
                </Col>
                <Col span={12} >
                    <Item label="生成业务名" name={"businessName"} labelCol={{ span: 4 }} tooltip="可理解为功能英文名，例如 user" required>
                        <Input placeholder="请输入业务名" />
                    </Item>
                </Col>
                <Col span={12} >
                    <Item label="生成功能名" name={"functionName"} labelCol={{ span: 4 }} tooltip="用作类描述，例如 用户" required>
                        <Input placeholder="请输入功能名" />
                    </Item>
                </Col>
                <Col span={12} >
                    <Item label="上级菜单" name={"parentMenuId"} labelCol={{ span: 4 }} tooltip="分配到指定菜单下，例如 系统管理" required>
                        <TreeSelect placeholder="请输入上级菜单" treeData={treeData} />
                    </Item>
                </Col>
                <Col span={24} >
                    <Item label="生成代码方式" name={"genType"} labelCol={{ span: 2 }} tooltip="默认为zip压缩包下载，也可以自定义生成路径">
                        <Radio.Group onChange={(e: RadioChangeEvent) => {
                            setGenType(e.target.value)

                        }}>
                            <Radio value="0">zip压缩包</Radio>
                            <Radio value="1">自定义路径</Radio>
                        </Radio.Group>
                    </Item>
                </Col>
                {genType == "1" ? <Col span={24} >
                    <Item label="自定义路径" name={"genPath"} labelCol={{ span: 2 }} tooltip="填写磁盘绝对路径，若不填写，则生成到当前Web项目下">
                        <Input placeholder="请输入自定义路径" />
                    </Item>
                </Col> : null}

            </Row>
            {
                form.getFieldValue('tplCategory') == 'sub' ? (
                    <>
                        <h4 className='form-header'>关联信息</h4>
                        <Row gutter={[32, 24]}>
                            <Col span={12} >
                                <Item label="关联子表的表名" name={"subTableName"} labelCol={{ span: 5 }} tooltip="关联子表的表名， 如：sys_user" required>
                                    <Select placeholder="请选择" options={tableOptions} onChange={(value, option: any) => {
                                        setTableFieldOptions(handleTableFieldOptions(option.columns))
                                    }} />
                                </Item>
                            </Col>
                            <Col span={12} >
                                <Item label="子表关联的外键名" name={"subTableFkName"} labelCol={{ span: 5 }} tooltip="如：user_id" required>
                                    <Select placeholder="请选择" options={tableFieldOptions} />
                                </Item>
                            </Col>
                        </Row>
                    </>
                ) : null
            }
            {
                form.getFieldValue('tplCategory') == 'tree' ? (
                    <>
                        <h4 className='form-header'>其他信息</h4>
                        <Row gutter={[32, 24]}>
                            <Col span={12} >
                                <Item label="树编码字段" name={"treeCode"} labelCol={{ span: 4 }} tooltip="树显示的编码字段名， 如：dept_id" required>
                                    <Select placeholder="请选择" options={culumnOptions} />
                                </Item>
                            </Col>
                            <Col span={12} >
                                <Item label="树父编码字段" name={"treeParentCode"} labelCol={{ span: 4 }} tooltip="树显示的父编码字段名， 如：parent_Id" required>
                                    <Select placeholder="请选择" options={culumnOptions} />
                                </Item>
                            </Col>
                            <Col span={12} >
                                <Item label="树名称字段" name={"treeName"} labelCol={{ span: 4 }} tooltip="树节点的显示名称字段名， 如：dept_name" required>
                                    <Select placeholder="请选择" options={culumnOptions} />
                                </Item>
                            </Col>
                        </Row>
                    </>
                ) : null
            }

        </Form>
    )
}
export default GenInfoForm;